觸發條件的種類介紹先暫停一下,先來進一步聊聊應用指令的說參數與說明。
今天會介紹應用指令的參數,以及如何添加說明,幫助使用者可以更容易使用。
相信大家還記得,昨天介紹的訊息指令和用戶指令有一個限制:函數需要有「剛好」兩個參數。
至於斜線指令,在前天的範例中只有使用一個參數。但其實,斜線指令的參數是「至少」一個 (第一個參數也是一定要是 interaction)。如果還有設定其他參數,就會要求使用者在使用斜線指令時,輸入在指令的後面。換句話說,透過適當的設計,可以讓使用者可以在使用斜線指令時,依照自己的需求去設定參數。
這邊來看一個斜線指令範例 (前後的程式碼先省略了,完整的程式碼可以參考昨天或前天的文章)。
# ...
@client.tree.command()
async def hello(interaction: discord.Interaction, name: str):
"""Says hello!"""
await interaction.response.send_message(f'Hi, {name}')
# ...
輸入斜線,看到我們建立的斜線指令 /hello
:
當游標移到上方時,可以看到後面多了一個 name
,表示這個斜線指令需要再額外提供一個叫做 name
的參數。
點擊之後,就可以看到除了 /hello
之外,還有一個 name
輸入框。
接著隨意輸入一個名字。
送出後,就可以看到剛剛輸入在 name 輸入框的內容,有成功地被使用。
如果有需要,參數的數量還可以繼續增加。接下來,來看看有三個參數的斜線指令。
# ...
@client.tree.command()
async def add_string(interaction: discord.Interaction, x: str, y: str):
"""Add two strings"""
await interaction.response.send_message(f'運算結果:{x + y}')
@client.tree.command()
async def add_number(interaction: discord.Interaction, x: int, y: int):
"""Add two numbers"""
await interaction.response.send_message(f'運算結果:{x + y}')
# ...
這兩個斜線指令非常像,除了名稱和 type hint 的型別不同之外,其他都相同。
先來看看 /add_number
再來看看 /add_string
可以看到,這兩個斜線指令都可以順利地取得所有參數並運算出結果。
透過使用 Optional
,就可以讓參數變成選填 (要填不填都可以)。
from typing import Optional
# ...
@client.tree.command()
async def add_number(interaction: discord.Interaction, x: int, y: Optional[int] = 9527):
"""Add two numbers"""
await interaction.response.send_message(f'運算結果:{x + y}')
# ...
在斜線指令選單時,就可以看到有選填的選項。
一開始只會看到一個輸入框。
此時如果直接送出,斜線指令是可以正常運作的。
但如果離開輸入框,就會看到可以選擇的參數。
選擇之後就會有第二個輸入框,並且它可以取代掉預設值。
兩個斜線指令看起來都很合理,都有照預期地出現數字相加或字串相加的結果。
但是,大家有沒有想過,為什麼這兩個函數的內容相同卻會有不同的結果?而這兩個函數基本上只有 type hint 是不同的,所以,也可以把問題改成是:為什麼這邊的 type hint 會影響程式結果?
在回答這個問題之前,大家可以再思考另一個問題:昨天介紹的訊息指令與用戶指令,它們其實也只有 type hint 不同,但為什麼最終的效果卻也不一樣,一個要對訊息使用,另一個則是對用戶使用?
相信大家應該隱隱約約有感受出答案了,這一切的幕後主使背後機制就是:discord.py
去取得型別並做對應的處理,包含驗證與轉換型別。也因此,一定要在幫所有參數設好型別 (一定要加 type hint,不然會報錯)。
甚至如果輸入的型別 (或格式) 不正確,參數的輸入框會變成紅色。如果依然強行送出的話,視窗會震動並收到錯誤提示。
最後,補充一下,應用指令和參數的說明是可以另外設定的,讓我們直接來看範例:
# ...
@client.tree.command(name="整數相加", description="幫你把兩個整數相加")
@app_commands.describe(x = "輸入整數", y = "輸入整數")
async def add_number(interaction: discord.Interaction, x: int, y: int):
await interaction.response.send_message(f'運算結果:{x + y}')
# ...
效果如下:
原則上
name
還是盡量用英文啦,這邊只是想展示用中文也可以XD
今天介紹了應用指令的參數,包含:
明天會繼續介紹除了型別之外,如何限制使用者輸入的參數。
今天是 PyCon 第一天,好多精彩的分享,但也害我沒時間寫文章QQ